4-4 webpack命令build构建过程解析
Webpack 构建流程概览
基于前一节对 webpack-cli 的分析,当 cli 调用 webpack(config) 后,Webpack 核心的构建流程开始执行。整个过程可以分为以下阶段:
webpack(config)
├── 1. createCompiler() 创建编译器
│ ├── 合并默认配置
│ ├── 初始化插件
│ └── 触发 environment/afterEnvironment 钩子
├── 2. compiler.run() 执行构建
│ ├── 触发 beforeRun/run 钩子
│ ├── 3. compiler.compile() 编译阶段
│ │ ├── 触发 make 钩子
│ │ ├── 从 entry 出发构建依赖图
│ │ └── 使用 Loader 处理各类文件
│ ├── 4. seal() 封装阶段
│ │ ├── 代码分割
│ │ ├── Tree Shaking
│ │ └── 生成 Chunk
│ ├── 5. emitAssets() 输出阶段
│ │ ├── 触发 emit 钩子
│ │ ├── 生成最终代码
│ │ └── 写入文件系统
│ └── 触发 done 钩子
└── 返回构建统计信息
text
各阶段详解
1. 创建编译器(createCompiler)
createCompiler 在 lib/webpack.js 中,负责初始化编译器实例:
const createCompiler = (rawOptions) => {
const options = new WebpackOptionsApply().process(rawOptions);
const compiler = new Compiler(options.context);
compiler.options = options;
if (options.plugins) {
for (const plugin of options.plugins) {
plugin.apply(compiler);
}
}
compiler.hooks.environment.call();
compiler.hooks.afterEnvironment.call();
return compiler;
};
javascript
2. 执行构建(compiler.run)
run 方法是构建的入口,依次触发 beforeRun 和 run 钩子后进入编译阶段。
3. 编译阶段(compile)
编译阶段的核心是构建模块依赖图。make 钩子触发后,EntryPlugin 会从入口开始递归解析所有模块的依赖关系。
4. 封装阶段(seal)
seal 阶段负责代码优化和 Chunk 生成:代码分割、Tree Shaking、生成最终 Chunk。
5. 输出阶段(emitAssets)
将生成的代码写入文件系统,触发 emit 和 afterEmit 钩子。
Compiler 与 Compilation 的关系
| 对象 | 生命周期 | 职责 |
|---|---|---|
| Compiler | 全局唯一,贯穿整个构建 | 管理配置、文件系统、插件注册 |
| Compilation | 每次构建创建一个 | 管理模块依赖图、代码生成 |
核心钩子的触发顺序
environment → afterEnvironment → entryOption → afterPlugins
→ beforeRun → run → compile → make → finishMake
→ finish → seal → afterCompile → shouldEmit → emit
→ afterEmit → done
text
理解这个顺序对于开发自定义 Plugin 至关重要。
参考资源
- Webpack Compiler Hooks - 官方钩子列表
- Webpack Compilation API - 编译阶段 API
↑